/* 
 * File:   estat_main.c
 * Author: oddi
 *
 * Created on January 20, 2010, 11:38 AM
 */

#include "inc/core/global_definitions.h"
#include "stdio.h"
#include "inc/core/task1d.h"

#define NPTS    2047

#ifdef __WINDOWS__
#define HOMEDIR "C:/es1/savedir"
#elif __LINUX__
#define HOMEDIR "/home/oddi/Code/edistr/test"
#endif


void mirror_b_field(time t, floatdig pos, floatdig* field) {
    if (field != NULL) {
        *field = B0;
    }
}

void uniform_e_field(time t, floatdig pos, floatdig* field) {
    if (field != NULL) {
        floatdig Dz = pos - PULSECENTRE_ZPOS;
        floatdig DtI = t - (PULSEDELAY);
        floatdig DtD = t - (PULSEDELAY + PULSEINCTIME);
        floatdig Az = exp(- pow((Dz / PULSEWIDTH / 0.3),6));
        floatdig AtI = pow(DtI / PULSEINCTIME / 0.1, 2);
        floatdig AtD = pow(DtD / PULSEDELTIME / 0.4, 2);
        floatdig osc = sin(WCE * t);
        if ((DtI >= 0) && (DtI <= PULSEINCTIME)) {
            *field = E0 * Az * (1 - exp(-AtI)) * osc;
            return;
        } else
            if ((DtD >= 0) && (DtD <= PULSEDURATION)) {
            *field = E0 * Az* (1/(1+AtD)) * osc;
            return;
        } else {
            *field = 0;
            return;
        }
    }
}

int main(int argc, char** argv) {
    task1d task = {0};
    particles_set set = {0};
    mover1d mover = {0};
    mover1d_parameters mparam = {0};
    init_ucgrid1d grid_param = {0};
    ucgrid1d grid = {0};
    pgm_set pgm = {0};
    boundary_conditions_uc1d bonds;
    bonds.l_phi = 0;
    bonds.r_phi = 0;
    bonds.max_z = MAXZ;
    bonds.min_z = MINZ;


    task1d_add_esource(&task, uniform_e_field);
    task1d_add_bsource(&task, mirror_b_field);

    particle_initialize_particle_set(&set, NPARTICLES, ELECTRON_CHARGE, ELECTRON_MASS);

    grid_param.cell_size = CELLSIZE;
    grid_param.l_phi = 0;
    grid_param.r_phi = 0;
    grid_param.min_z = MINZ;
    grid_param.max_z = MAXZ;
    ucgrid1d_init_grid(&grid_param, &grid);
    particle_distrubute_particles_set_pos_uniform(&set, Z, 0, L);;
    particle_distribute_particle_set_beam(&set, 0, VZ);
    particle_distribute_particle_set_beam(&set, 0, VX);
    particle_distribute_particle_set_beam(&set, 0, VY);
    particle_distribute_particle_set_speed_maxwell(&set, SIGMA, VX);
    particle_distribute_particle_set_speed_maxwell(&set, SIGMA, VY);
    particle_distribute_particle_set_speed_maxwell(&set, SIGMA, VZ);
    //particle_make_pos_disturbance(&set, 1*cell_size, 2*PI/L, Z);
    ebsources_plot_t_profile_esource(HOMEDIR, "e_t.dat", uniform_e_field, PULSECENTRE_ZPOS, 0, 10 * PULSEDURATION, DT);
    ebsources_plot_z_profile_esource(HOMEDIR, "e_z.dat", uniform_e_field, PULSEDELAY + PULSEINCTIME, 0, L, CELLSIZE);

    //particle_dump_particles_speed_into_file(&set, HOMEDIR, "full_speed.dat", 0, -1);
    //particle_dump_particles_pos_into_file(&set, HOMEDIR, "full_pos.dat", 0, -1);

    mparam.dt = DT;
    mparam.grid = &grid;
    mparam.set = &set;
    mparam.sources = &(task.sources);
    mover1d_setup_mover(&mparam, &mover);

    pgm.grid = &grid;
    pgm.mover = &mover;
    pgm.set = &set;

    task1d_set_add_pgd(&task, &pgm);
    task1d_set_boundaries(&task, &bonds);
    task.current_time = 0;
    task.start_time = 0;
    task.end_time = CYCLES*DT;
    task.dt = DT;

    task1d_start_evaluations(&task);

    particle_clear_particle_set(&set);
    ucgrid1d_clear_grid(&grid);
    mover1d_clear_mover(&mover);
    task1d_clear_task(&task);
    return 0;
}
